package com.auxgroup.hr.front.commons.utils;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.beanutils.BeanUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 当把Person类作为BeanUtilTest的内部类时，程序出错<br>
 * java.lang.NoSuchMethodException: Property '**' has no setter method<br>
 * 本质：内部类 和 单独文件中的类的区别 <br>
 * BeanUtils.populate方法的限制：<br>
 * The class must be public, and provide a public constructor that accepts no
 * arguments. <br>
 * This allows tools and applications to dynamically create new instances of
 * your bean, <br>
 * without necessarily knowing what Java class name will be used ahead of time
 */
public class Bean2MapUtils {

	private static final Logger logger = LoggerFactory
			.getLogger(Bean2MapUtils.class);

	/**
	 * // Map --> Bean 2: 利用org.apache.commons.beanutils 工具类实现 Map --> Bean
	 * 
	 * @param map
	 * @param obj
	 */
	public static void transMap2Bean2(Map<String, Object> map, Object obj) {
		if (map == null || obj == null) {
			return;
		}
		try {
			BeanUtils.populate(obj, map);
		} catch (Exception e) {
			logger.error("Map --> Bean error", e);
		}
	}

	/**
	 * // Map --> Bean 1: 利用Introspector,PropertyDescriptor实现 Map --> Bean
	 * 
	 * @param map
	 * @param obj
	 */
	public static void transMap2Bean(Map<String, Object> map, Object obj) {
		try {
			BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
			PropertyDescriptor[] propertyDescriptors = beanInfo
					.getPropertyDescriptors();
			for (PropertyDescriptor property : propertyDescriptors) {
				String key = property.getName();
				if (map.containsKey(key)) {
					Object value = map.get(key);
					// 得到property对应的setter方法
					Method setter = property.getWriteMethod();
					setter.invoke(obj, value);
				}
			}
		} catch (Exception e) {
			logger.error("transMap2Bean Error ", e);
		}
		return;
	}

	// Bean --> Map 1: 利用Introspector和PropertyDescriptor 将Bean --> Map
	public static Map<String, Object> transBean2Map(Object obj, Boolean isTrim) {
		if (obj == null) {
			return null;
		}
		Map<String, Object> map = new HashMap<String, Object>();
		String[] fieldNames = ObjectFieldUtils.getFiledName(obj);
		for (String field : fieldNames) {
			Object fieldVal = ObjectFieldUtils.getFieldValueByName(field, obj);
			// 如果是字符串则清空掉空格
			if (isTrim && fieldVal instanceof String) {
				map.put(field, fieldVal.toString().trim());
			} else {
				map.put(field, fieldVal);
			}
		}
		return map;
	}
}